package com.huang.security.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.huang.entity.Role;
import com.huang.entity.SecurityUser;
import com.huang.entity.UserPo;
import com.huang.enums.AuthenticationMethodEnum;
import com.huang.enums.PasswordEncoderTypeEnum;
import com.huang.mapper.RoleDao;
import com.huang.mapper.UserDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author han
 * @since 2022-01-16 18:41:46
 */
@Component
public class CustomUserDetailsService implements UserDetailsService {

    private static final Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class);

    @Resource
    private UserDao userDao;
    @Resource
    private RoleDao roleDao;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        logger.info("查询用户：{} 的信息...", username);
        if (StrUtil.isBlank(username)) {
            logger.error("手机号码不能为空！");
            throw new UsernameNotFoundException("手机号码不能为空！");
        }

        // 查询用户信息
        QueryWrapper<UserPo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserPo::getUsername, username);
        UserPo userPo = userDao.selectOne(queryWrapper);
        if (userPo == null) {
            logger.error("用户：{}，不存在！", username);
            throw new UsernameNotFoundException("用户：" + username + "，不存在");
        }
        if (userPo.getDeleted() == 1) {
            logger.error("用户：{}，被锁定！", username);
            throw new UsernameNotFoundException("用户：" + username + "，被锁定");
        }
        // 查询角色信息
        List<Role> roles = roleDao.findByUserId(userPo.getId());
        if (CollectionUtils.isEmpty(roles)) {
            logger.error("用户：{}，未分配角色！", username);
            throw new UsernameNotFoundException("用户：" + username + "，未分配角色");
        }
        Set<GrantedAuthority> authorities = new HashSet<>();
        roles.forEach(role -> authorities.add(new SimpleGrantedAuthority(role.getCode())));
        if (CollectionUtils.isEmpty(authorities)) {
            logger.error("用户：{}，未分配权限！", username);
            throw new UsernameNotFoundException("用户：" + username + "，未分配权限");
        }
        userPo.setPassword(PasswordEncoderTypeEnum.NOOP.getPrefix() + userPo.getPassword());
        SecurityUser user = new SecurityUser(userPo, authorities);
        user.setAuthenticationMethod(AuthenticationMethodEnum.USERNAME.getValue());
        return user;
    }

    public UserDetails loadUserByMobile(String phone) {
        logger.info("短信登录");
        logger.info("根据手机号码查询用户：{} 的信息...", phone);
        if (StrUtil.isBlank(phone)) {
            logger.error("手机号码不能为空！");
            throw new UsernameNotFoundException("手机号码不能为空！");
        }

        // 查询用户信息
        QueryWrapper<UserPo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserPo::getPhone, phone);
        UserPo userPo = userDao.selectOne(queryWrapper);
        if (userPo == null) {
            logger.error("用户：{}，不存在！", phone);
            throw new UsernameNotFoundException("用户：" + phone + "，不存在");
        }
        if (userPo.getDeleted() == 1) {
            logger.error("用户：{}，被锁定！", phone);
            throw new UsernameNotFoundException("用户：" + phone + "，被锁定");
        }

        // 查询角色信息
        List<Role> roles = roleDao.findByUserId(userPo.getId());
        if (CollectionUtils.isEmpty(roles)) {
            logger.error("用户：{}，未分配角色！", phone);
            throw new UsernameNotFoundException("用户：" + phone + "，未分配角色");
        }
        Set<GrantedAuthority> authorities = new HashSet<>();
        roles.forEach(role -> {
            authorities.add(new SimpleGrantedAuthority(role.getCode()));
        });
        if (CollectionUtils.isEmpty(authorities)) {
            logger.error("用户：{}，未分配权限！", phone);
            throw new UsernameNotFoundException("用户：" + phone + "，未分配权限");
        }
        SecurityUser user = new SecurityUser(userPo, authorities);
        user.setAuthenticationMethod(AuthenticationMethodEnum.MOBILE.getValue());
        return user;
    }
}
